﻿using System;
using System.Text;
using System.Text.RegularExpressions;
using log4net;

namespace TimeMachine.Engine.Vcs.Svn
{
	public class SvnLogProvider : ISvnLogProvider
	{
		private static readonly ILog log = LogManager.GetLogger(typeof (SvnLogProvider));
		private readonly IVcsRepo repo;
		private readonly Regex revisionRegex = new Regex(@"Last Changed Rev: (\d+)", RegexOptions.Multiline | RegexOptions.Compiled);
		private readonly ISvnExecutor svn;

		public SvnLogProvider(IVcsRepo repo, ISvnExecutor svn)
		{
			this.repo = repo;
			this.svn = svn;
		}

		#region ISvnLogProvider Members

		public byte[] GetLogFrom(int fromRev)
		{
			string output;
			if (fromRev > GetLastRevision())
			{
				output = "<log/>";
				log.Info("Ничего нового...");
			}
			else
			{
				log.Info("Получаем информацию о новых коммитах из репозитория...");
				string revRange = fromRev == 0 ? "" : "-r HEAD:" + fromRev;
				output = svn.Execute("log -v --xml " + revRange + " " + repo.Url);
			}
			return Encoding.UTF8.GetBytes(output);
		}

		#endregion

		private int GetLastRevision()
		{
			string info = svn.Execute("info {0}", repo.Url);
			MatchCollection collection = revisionRegex.Matches(info);
			if (collection.Count != 1)
				throw new Exception("Ошибка при разборе результатов svn info. Невозможно определить последнюю ревизию репозитория.");
			string rev = collection[0].Groups[1].Value;
			return int.Parse(rev);
		}
	}

	public interface ISvnLogProvider
	{
		byte[] GetLogFrom(int fromRev);
	}
	
	public static class SvnLogProviderExtensions
	{
		public static byte[] GetFullLog(this ISvnLogProvider provider)
		{
			return provider.GetLogFrom(0);
		}
	}
}